package com.ynet.middleground.contract.service.impl;

import java.util.Date;
import java.util.List;

import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.base.Throwables;
import com.ynet.core.common.ServiceResult;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.middleground.contract.bean.*;
import com.ynet.middleground.contract.dto.*;
import com.ynet.middleground.contract.model.SignModel;
import com.ynet.middleground.contract.service.SignService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

/**
 * @author liulx
 * @description 签名签章接口服务
 * @date 2020-04-12 00:22
 */
@Produces({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Consumes({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Api(value = "签名签章接口服务", tags = {"签名签章接口服务"})
@Path("sign")
@Service(timeout = 80000, version = "0.0.1")
public class SignServiceImpl implements SignService, GenericService {

    @Autowired
    SignModel signModel;

    /**
     * 文本签加密
     *
     * @param textSignReq 文本签请求类
     * @return 文本签结果数据
     */
    @POST
    @Path("text")
    @ApiOperation(value = "e 签宝-文本签服务", notes = "用指定账户的证书对文本数据进行摘要，并对摘要结果进行签名。签名过程需要校验用户短信验证码，验证码必须通过 e 签宝接口发送")
    @ApiImplicitParam(name = "requestObj", dataType = "TextSignReq", paramType = "body", required = true)
    @Override
    public ServiceResult<TextSignResultDTO> textSign(@Valid TextSignReq textSignReq) {
        ServiceResult<TextSignResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.textSign(textSignReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "文本签加密服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 文本签验签服务
     *
     * @param verifyTextSignReq 文本签验签请求类
     * @return 文本签名证书信息
     */
    @POST
    @Path("text-verify")
    @ApiOperation(value = "e 签宝-文本签验签服务", notes = "文本签验签服务，验证文本签名成功接口返回文本签名证书信息")
    @ApiImplicitParam(name = "requestObj", dataType = "VerifyTextSignReq", paramType = "body", required = true)
    @Override
    public ServiceResult<EsignCertDTO> verifyTextSign(@Valid VerifyTextSignReq verifyTextSignReq) {
        ServiceResult<EsignCertDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.verifyTextSign(verifyTextSignReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "文本签验签服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * pdf 文档验签
     *
     * @param verifyPdfSignReq pdf 文档验签请求信息
     * @return pdf 文档所有签名信息列表
     */
    @POST
    @Path("pdf-verify")
    @ApiOperation(value = "e 签宝-pdf 文档验签", notes = "使用 e 签宝服务, pdf 文档验签，验证成功接口返回文档里签名信息")
    @ApiImplicitParam(name = "requestObj", dataType = "VerifyPdfSignReq", paramType = "body", required = true)
    @Override
    public ServiceResult<List<SignBeanDTO>> verifyPdfSign(@Valid VerifyPdfSignReq verifyPdfSignReq) {
        ServiceResult<List<SignBeanDTO>> result = new ServiceResult<>();
        try {
            result.setResult(signModel.verifyPdfSign(verifyPdfSignReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "pdf 文档验签服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 时间戳加戳
     *
     * @param timestampReq 时间戳加戳请求信息
     * @return 加戳后数据包
     */
    @POST
    @Path("timestamp")
    @ApiOperation(value = "CFCA-时间戳加签服务", notes = "时间戳加签服务")
    @ApiImplicitParam(name = "requestObj", dataType = "TimestampReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> requestTimestamp(@Valid TimestampReq timestampReq) {
        ServiceResult<String> result = new ServiceResult<>();
        try {
            result.setResult(signModel.requestTimestamp(timestampReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "时间戳加签服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 时间戳验签
     *
     * @param verifyTimestampReq 时间戳验签请求信息
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("timestamp-verify")
    @ApiOperation(value = "CFCA-时间戳验签服务", notes = "时间戳验签服务，验证成功返回加戳的时间戳（毫秒）")
    @ApiImplicitParam(name = "requestObj", dataType = "VerifyTimestampReq", paramType = "body", required = true)
    @Override
    public ServiceResult<Date> verifyTimestamp(@Valid VerifyTimestampReq verifyTimestampReq) {
        ServiceResult<Date> result = new ServiceResult<>();
        try {
            result.setResult(signModel.verifyTimestamp(verifyTimestampReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "时间戳验签服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 发送签署验证短信，e 签宝签名服务时需要验证码，可调用此接口获取验证码
     *
     * @param sendSignMobileCodeReq 发送签署短信验证码类
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("send-code")
    @ApiOperation(value = "e 签宝-发送签署短信验证码", notes = "发送签署验证短信，使用 e 签宝签名类服务时需要验证码，可调用此接口获取验证码")
    @ApiImplicitParam(name = "requestObj", dataType = "SendSignMobileCodeReq", paramType = "body", required = true)
    @Override
    public ServiceResult sendSignMobileCode(@Valid SendSignMobileCodeReq sendSignMobileCodeReq) {
        ServiceResult result = new ServiceResult<>();
        try {
            signModel.sendSignMobileCode(sendSignMobileCodeReq);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "发送签署短信验证码服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 指定手机发送签署短信验证码
     *
     * @param sendAppointSignMobileCodeReq 指定手机发送签署短信验证码类
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("send-appoint-mobile-code")
    @ApiOperation(value = "e 签宝-指定手机号发送签署短信验证码", notes = "发送签署验证短信，使用 e 签宝签名类服务时需要验证码，可调用此接口指定手机号发送签署短信验证码")
    @ApiImplicitParam(name = "requestObj", dataType = "SendAppointSignMobileCodeReq", paramType = "body",
        required = true)
    @Override
    public ServiceResult sendAppointSignMobileCode(@Valid SendAppointSignMobileCodeReq sendAppointSignMobileCodeReq) {
        ServiceResult result = new ServiceResult<>();
        try {
            signModel.sendAppointSignMobileCode(sendAppointSignMobileCodeReq);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "指定手机发送签署短信验证码服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * PDF 摘要签署（短信验证）
     *
     * @param signPdfReq PDF 文件签署请求类
     * @return 文件签署结果
     */
    @POST
    @Path("sign-code")
    @ApiOperation(value = "e 签宝-pdf 摘要签署（短信验证）", notes = "协议签，pdf 摘要签署（短信验证）")
    @ApiImplicitParam(name = "requestObj", dataType = "SignPdfReq", paramType = "body", required = true)
    @Override
    public ServiceResult<SignedResultDTO> userSignPdf(@Valid SignPdfReq signPdfReq) {
        ServiceResult<SignedResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.userSignPdf(signPdfReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "e 签宝 pdf 摘要签署服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 平台用户PDF文件批量签署（指定手机号短信验证）
     *
     * @param batchSignPdfAppointMobileReq 平台用户PDF文件批量签署（指定手机号短信验证）请求类
     * @return 文件签署结果
     */
    @POST
    @Path("batch-sign-appoint-mobile-code")
    @ApiOperation(value = "e 签宝-平台用户 pdf 文件批量签署（指定手机号短信验证）", notes = "e 签宝-平台用户 pdf 文件批量签署（指定手机号短信验证）")
    @ApiImplicitParam(name = "requestObj", dataType = "BatchSignPdfAppointMobileReq", paramType = "body",
        required = true)
    @Override
    public ServiceResult<MultiSignedResultDTO>
        batchSignAppointMobilePdfReq(@Valid BatchSignPdfAppointMobileReq batchSignPdfAppointMobileReq) {
        ServiceResult<MultiSignedResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.batchSignAppointMobilePdfReq(batchSignPdfAppointMobileReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "平台用户PDF文件批量签署（指定手机号短信验证）服务异常, case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 批量 PDF 摘要签署（短信验证）
     *
     * @param batchSignPdfReq PDF 文件批量签署（短信验证）请求类
     * @return 文件签署结果
     */
    @POST
    @Path("batch-sign-code")
    @ApiOperation(value = "e 签宝-批量 pdf 摘要签署（短信验证）", notes = "协议签，批量 pdf 摘要签署（短信验证）")
    @ApiImplicitParam(name = "requestObj", dataType = "BatchSignPdfReq", paramType = "body", required = true)
    @Override
    public ServiceResult<MultiSignedResultDTO> batchSignPdfReq(@Valid BatchSignPdfReq batchSignPdfReq) {
        ServiceResult<MultiSignedResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.batchSignPdfByCode(batchSignPdfReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "批量文件意愿签署（短信验证码）服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * e签宝-平台用户无认证PDF文件签署
     * 
     * @param signWithoutAuthReq e签宝-平台用户无认证PDF文件签署请求类
     * @return 文件签署结果
     */
    @POST
    @Path("sign-without-auth")
    @ApiOperation(value = "e 签宝-平台用户无认证 pdf 文件签署", notes = "e 签宝-平台用户无认证 pdf 文件签署")
    @ApiImplicitParam(name = "requestObj", dataType = "SignWithoutAuthReq", paramType = "body", required = true)
    @Override
    public ServiceResult<SignWithoutAuthResultDTO> signWithoutAuth(@Valid SignWithoutAuthReq signWithoutAuthReq) {
        ServiceResult<SignWithoutAuthResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.signWithoutAuth(signWithoutAuthReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "e签宝-平台用户无认证PDF文件签署服务异常, case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 上传文件并同时调用 e签宝无认证 PDF 文件签署，对文件进行签章
     *
     * @param req 上传文件并进行无认证签章请求信息
     * @return 文件签署结果
     */
    @POST
    @Path("upload-file-and-sign-without-auth")
    @ApiOperation(value = "上传文件并同时调用 e 签宝无认证 PDF 文件签署", notes = "上传文件并同时调用 e签宝无认证 PDF 文件签署，对文件进行签章")
    @ApiImplicitParam(name = "requestObj", dataType = "UploadFileAndSignWithoutAuthReq", paramType = "body",
        required = true)
    @Override
    public ServiceResult<UploadAndSignWithoutAuthResultDTO>
        uploadFileAndSignWithoutAuth(@Valid UploadFileAndSignWithoutAuthReq req) {
        ServiceResult<UploadAndSignWithoutAuthResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.uploadFileAndSignWithoutAuth(req));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "上传文件并同时调用 e 签宝无认证 PDF 文件签署服务异常, case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 批量文件意愿签署（用于人脸确认）
     *
     * @param signPdfWithWillnessReq PDF 文件意愿签署请求类
     * @return 批量签署结果
     */
    @POST
    @Path("sign-willness")
    @ApiOperation(value = "e 签宝-pdf 摘要签署（人脸验证）",
        notes = "协议签，pdf 摘要签署（人脸验证）<br /> 人脸意愿验证签署步骤：<br/>"
            + "1. 先调用<b>e 签宝-获取意愿地址</b>接口，获得人脸意愿验证地址<br />2. 用户打开人脸意愿验证地址，进行刷脸认证<br/>"
            + "3. 认证完成可进行调用<b>e 签宝-pdf 摘要签署（人脸验证）</b>接口进行文件签署<br/>人脸验证期间可调用<b>e 签宝-查询意愿状态</b>接口查看用户人脸验证的状态")
    @ApiImplicitParam(name = "requestObj", dataType = "SignPdfWithWillnessReq", paramType = "body", required = true)
    @Override
    public ServiceResult<MultiSignedResultDTO>
        batchWillnessSignPdf(@Valid SignPdfWithWillnessReq signPdfWithWillnessReq) {
        ServiceResult<MultiSignedResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.batchWillnessSignPdf(signPdfWithWillnessReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "批量文件意愿签署（用于人脸确认）服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 获取意愿地址
     *
     * @param createSignAuthReq 获取意愿地址请求类
     * @return 意愿任务信息
     */
    @POST
    @Path("get-willness-url")
    @ApiOperation(value = "e 签宝-获取意愿地址",
        notes = "获取人脸意愿地址，人脸验证前使用<br /> 人脸意愿验证签署步骤：<br/>"
            + "1. 先调用<b>e 签宝-获取意愿地址</b>接口，获得人脸意愿验证地址<br />2. 用户打开人脸意愿验证地址，进行刷脸认证<br/>"
            + "3. 认证完成可进行调用<b>e 签宝-pdf 摘要签署（人脸验证）</b>接口进行文件签署<br/>人脸验证期间可调用<b>e 签宝-查询意愿状态</b>接口查看用户人脸验证的状态")
    @ApiImplicitParam(name = "requestObj", dataType = "CreateSignAuthReq", paramType = "body", required = true)
    @Override
    public ServiceResult<SignAuthBizDTO> createSignAuth(@Valid CreateSignAuthReq createSignAuthReq) {
        ServiceResult<SignAuthBizDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.createSignAuth(createSignAuthReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "获取意愿服务地址服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 查询意愿状态
     *
     * @param queryWillAuthReq 获取意愿地址请求类
     * @return 意愿状态信息
     */
    @POST
    @Path("query-willness")
    @ApiOperation(value = "e 签宝-查询意愿状态",
        notes = "查询意愿状态，可查询人脸识别状态<br /> 人脸意愿验证签署步骤：<br/>"
            + "1. 先调用<b>e 签宝-获取意愿地址</b>接口，获得人脸意愿验证地址<br />2. 用户打开人脸意愿验证地址，进行刷脸认证<br/>"
            + "3. 认证完成可进行调用<b>e 签宝-pdf 摘要签署（人脸验证）</b>接口进行文件签署<br/>人脸验证期间可调用<b>e 签宝-查询意愿状态</b>接口查看用户人脸验证的状态")
    @ApiImplicitParam(name = "requestObj", dataType = "QueryWillAuthReq", paramType = "body", required = true)
    @Override
    public ServiceResult<WillAuthDTO> queryWillAuth(@Valid QueryWillAuthReq queryWillAuthReq) {
        ServiceResult<WillAuthDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.queryWillAuth(queryWillAuthReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "查询意愿状态服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * cfca 自动化计算 pdf 签署 hash 值
     *
     * @param calculatePdfHashReq 计算 pdf 签章 hash 值请求类
     * @return hash 值信息
     */
    @POST
    @Path("calculate-hash")
    @ApiOperation(value = "CFCA-自动化计算 pdf 签署 Hash 值",
        notes = "协议签，使用 CFCA 服务，自动化计算 pdf 签署 Hash 值<br/>"
            + "CFCA 协议签的步骤：<br />1、调用<b>CFCA-自动化计算 pdf 签署 Hash 值</b>接口计算并获取 Hash 值<br />"
            + "2、用户使用 UKey（证书）对 Hash 值进行签名并获取签名值<br />3、调用<b>CFCA-pdf 合成外部签名</b>接口，将签名值合成到 PDF 文件中")
    @ApiImplicitParam(name = "requestObj", dataType = "CalculatePdfHashReq", paramType = "body", required = true)
    @Override
    public ServiceResult<PdfHashDTO> autoCalculatePdfHash(@Valid CalculatePdfHashReq calculatePdfHashReq) {
        ServiceResult<PdfHashDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.autoCalculatePdfHash(calculatePdfHashReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "CFCA 自动化计算 pdf 签署 Hash 值服务异常, case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * cfca pdf 文档验签
     *
     * @param verifyPdfSignReq pdf 文档验签请求信息
     * @return pdf 文档所有签名信息列表
     */
    @POST
    @Path("pdf-verify-cfca")
    @ApiOperation(value = "CFCA-pdf 文档验签", notes = "使用 CFCA 服务, pdf 文档验签，验证成功接口返回文档里签名信息")
    @ApiImplicitParam(name = "requestObj", dataType = "VerifyPdfSignReq", paramType = "body", required = true)
    @Override
    public ServiceResult<List<SignedCertDTO>> verifyPdfSignByCfca(@Valid VerifyPdfSignReq verifyPdfSignReq) {
        ServiceResult<List<SignedCertDTO>> result = new ServiceResult<>();
        try {
            result.setResult(signModel.verifyPdfSignByCfca(verifyPdfSignReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "cfca pdf 文档验签服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * Pdf合成外部签名
     *
     * @param synthesizeOuterSignatureReq Pdf合成外部签名请求类
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("pdf-synthesize")
    @ApiOperation(value = "CFCA-pdf 合成外部签名",
        notes = "协议签，使用 cfca 服务，Pdf合成外部签名，将合成后的 pdf 文件更新到至原文件地址 <br /> "
            + "CFCA 协议签的步骤：<br />1、调用<b>CFCA-自动化计算 pdf 签署 Hash 值</b>接口计算并获取 Hash 值<br />"
            + "2、用户使用 UKey（证书）对 Hash 值进行签名并获取签名值<br />" + "3、调用<b>CFCA-pdf 合成外部签名</b>接口，将签名值合成到 pdf 文件中")
    @ApiImplicitParam(name = "requestObj", dataType = "SynthesizeOuterSignatureReq", paramType = "body",
        required = true)
    @Override
    public ServiceResult<SignedResultDTO>
        synthesizeOuterSignature(@Valid SynthesizeOuterSignatureReq synthesizeOuterSignatureReq) {
        ServiceResult<SignedResultDTO> result = new ServiceResult<>();
        try {
            result.setResult(signModel.synthesizeOuterSignature(synthesizeOuterSignatureReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "CFCA pdf 合成外部签名服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

}
